package com.zzyl.framework.interceptor; // 包名，指定了该类的位置

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; // 导入 MyBatis-Plus 提供的接口
import com.zzyl.common.core.domain.model.LoginUser; // 导入自定义的 LoginUser 类
import com.zzyl.common.utils.SecurityUtils; // 导入自定义的安全工具类
import org.apache.ibatis.reflection.MetaObject; // 导入 MyBatis 提供的类
import org.springframework.stereotype.Component; // 导入 Spring 提供的注解

import java.util.Date; // 导入 Java 提供的 Date 类

/**
 * MyBatis-Plus 自动填充处理器
 * 用于在插入和更新数据时自动填充公共字段，例如创建时间、创建人、更新时间、更新人
 */
@Component // 使用 Spring 的 @Component 注解，将该类注册为一个 Spring Bean，使其可以被 Spring 管理
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入元对象填充，用于在执行插入操作时自动填充字段
     * @param metaObject 元对象，包含了要插入的数据对象的信息
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 使用 strictInsertFill 方法，严格地填充字段，如果字段不存在则不填充
        // 填充创建时间字段（createTime），类型为 Date，值为当前时间
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());

        // 填充创建人字段（createBy），类型为 String，值为当前登录用户的 ID
        this.strictInsertFill(metaObject, "createBy", String.class, String.valueOf(loadUserId())); // 将 Long 类型的用户 ID 转换为 String 类型
    }

    /**
     * 更新元对象填充，用于在执行更新操作时自动填充字段
     * @param metaObject 元对象，包含了要更新的数据对象的信息
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        // 使用 strictUpdateFill 方法，严格地填充字段，如果字段不存在则不填充
        // 填充更新时间字段（updateTime），类型为 Date，值为当前时间
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());

        // 填充更新人字段（updateBy），类型为 String，值为当前登录用户的 ID
        this.strictUpdateFill(metaObject, "updateBy", String.class, String.valueOf(loadUserId())); // 将 Long 类型的用户 ID 转换为 String 类型
    }

    /**
     * 获取当前登录人的ID
     * @return 登录人ID
     */
    public Long loadUserId() {
        // 使用 SecurityUtils 工具类获取当前登录用户的信息
        LoginUser loginUser = SecurityUtils.getLoginUser();

        // 如果登录用户存在，则返回其用户 ID
        if (loginUser != null) {
            return loginUser.getUserId();
        }

        // 如果登录用户不存在，则返回一个默认值（1L），通常用于系统自动执行的任务
        return 1L;
    }
}